package tw.com.hitevision.whiteboard.android.widgets;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import androidx.annotation.ColorInt;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import tw.com.hitevision.whiteboard.android.Device;
import tw.com.hitevision.whiteboard.android.R;
import tw.com.hitevision.whiteboard.android.state.HighlighterProperty;
import tw.com.hitevision.whiteboard.android.state.PenProperty;

import static com.crashlytics.android.Crashlytics.log;

public class FloatingBarView extends RelativeLayout {
    private HighlighterMenuView.OnChangeListener listener;
    private PenMenuView penMenuView;
    private View penMenuShadow;
    private HighlighterMenuView highlighterMenuView;
    private View highlighterMenuShadow;
    private ImageView penStroke;
    private ImageView highlighterStroke;
    private View inputPen;
    private View inputHighlighter;
    private View inputEraser;
    private View undo;
    private View takeScreenshot;
    private View inputExit;
    private View clearScreenBackground;
    private View clearScreen;
    private View clearScreenShadow;
    private View settingBackground;
    private View setting;
    private View settingShadow;
    private View shareBackground;
    private View share;
    private View shareShadow;
    private View[] inputGroup;
//    private PenProperty penProp;
    private PenProperty fingerPenProp;
    private PenProperty stylusPenProp;
    private HighlighterProperty fingerHighlighterProp;
    private HighlighterProperty stylusHighlighterProp;
//    private HighlighterProperty highlighterProp;
    private View.OnTouchListener toggleInputTouchListener;
    private FloatingBarListener floatingBarListener;

    private Context context;
    private @ColorInt int penDefault, highlighterDefault;


    public FloatingBarView(Context context) {
        super(context);
        init(context);
    }

    public FloatingBarView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public FloatingBarView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    public void setPenProp(PenProperty input){
//        this.penProp = input;
        if(input != null)
            updatePenUi(input);
    }

    public void setHighlighterProp(HighlighterProperty input){
//        this.highlighterProp = input;
        if(input != null)
            updateHighlighterUi(input);
    }

    public void setToggleInputTouchListener(View.OnTouchListener input){
        this.toggleInputTouchListener = input;
        inputPen.setOnTouchListener(toggleInputTouchListener);
        inputHighlighter.setOnTouchListener(toggleInputTouchListener);
        inputEraser.setOnTouchListener(toggleInputTouchListener);
    }

    public void setPenMenuOnTouchListener(View.OnTouchListener input){
        penMenuView.setOnTouchListener(input);
    }

    public void setHighlighterMenuOnTouchListener(View.OnTouchListener input){
        highlighterMenuView.setOnTouchListener(input);
    }



    @SuppressLint("ClickableViewAccessibility")
    private void init(Context context) {
        this.context = context;
        inflate(context, R.layout.menu_floating_toolbar, this);

        penDefault =ContextCompat.getColor(context, R.color.pen_red);
        highlighterDefault =  ContextCompat.getColor(context, R.color.highlight_yellow);

//        penProp = new PenProperty(penDefault, PenProperty.Size.ONE);
        stylusPenProp = new PenProperty(penDefault, PenProperty.Size.ONE);
        fingerPenProp = new PenProperty(penDefault, PenProperty.Size.ONE);
//        highlighterProp = new HighlighterProperty(highlighterDefault, HighlighterProperty.Size.TWO);
        fingerHighlighterProp = new HighlighterProperty(highlighterDefault, HighlighterProperty.Size.TWO);
        stylusHighlighterProp= new HighlighterProperty(highlighterDefault, HighlighterProperty.Size.TWO);
        inputGroup = new View[6];
        penMenuView = findViewById(R.id.pen_menu);
        highlighterMenuView = findViewById(R.id.highlighter_menu);
        penStroke = findViewById(R.id.pen_stroke);
        highlighterStroke = findViewById(R.id.highlighter_stroke);
        inputEraser = findViewById(R.id.input_eraser);
        inputHighlighter = findViewById(R.id.input_highlighter);
        inputPen = findViewById(R.id.input_pen);
        undo = findViewById(R.id.undo);
        clearScreen = findViewById(R.id.clear_screen);
        takeScreenshot = findViewById(R.id.screenshot);
        inputExit = findViewById(R.id.exit);
        setting = findViewById(R.id.setting);
        clearScreenBackground = findViewById(R.id.clear_screen_background);
        settingBackground = findViewById(R.id.setting_background);
        share = findViewById(R.id.share);
        shareBackground = findViewById(R.id.share_background);
        clearScreenShadow = findViewById(R.id.clear_screen_shadow);
        settingShadow = findViewById(R.id.setting_shadow);
        shareShadow = findViewById(R.id.share_shadow);
        penMenuShadow = findViewById(R.id.pen_menu_shadow);
        highlighterMenuShadow = findViewById(R.id.highlighter_menu_shadow);

        inputPen.setOnClickListener(v -> {
            if (v.isSelected()) {
                if(penMenuView.getVisibility() != VISIBLE  ){
                    toggleInput(v);
                    floatingBarListener.updateInputMode(InputMode.PEN);
                    hideMenus();
                    penMenuView.setVisibility(VISIBLE);
                    penMenuShadow.setVisibility(VISIBLE);
                } else {
                    hideMenus();
                }
            }else {
                hideMenus();
                toggleInput(v);
                floatingBarListener.updateInputMode(InputMode.PEN);

            }

        });
        penMenuView.setOnChangeListener(new PenMenuView.OnChangeListener() {
            @Override
            public void onSelectPenProp(Device device, int color, PenProperty.Size size) {
                log("onSelectPenProp: device=" + device + ", color=" + color + ", size=" + size);
                PenProperty penProp = device == Device.FINGER ? fingerPenProp : stylusPenProp;
                if(penProp != null){
                    penProp.setColor(color);
                    penProp.setSize(size);
                } else {
                    penProp = new PenProperty(color,size);
                }
                updatePenUi(penProp);
                penMenuView.setSize(size);
                penMenuView.setColor(color);
                floatingBarListener.updateCurrentPenPropertyFromFloatingBar(device,color,size);
            }
        });



        inputHighlighter.setOnClickListener(v -> {
            if (v.isSelected()) {
                if (highlighterMenuView.getVisibility() != View.VISIBLE) {
                    toggleInput(v);
                    hideMenus();
                    floatingBarListener.updateInputMode(InputMode.HIGHLIGHTER);
                    highlighterMenuView.setVisibility(VISIBLE);
                    highlighterMenuShadow.setVisibility(VISIBLE);
                } else {
                    hideMenus();
                }
            } else {
                toggleInput(v);
                hideMenus();
                floatingBarListener.updateInputMode(InputMode.HIGHLIGHTER);
            }
        });
        // init select
        inputHighlighter.setSelected(true);
        highlighterMenuView.setOnChangeListener(new HighlighterMenuView.OnChangeListener() {
            @Override
            public void onSelectHighlighterProp(Device device, int color, HighlighterProperty.Size size) {
                log("onSelectHighlighterProp: device=" + device + ", color=" + color + ", size=" + size);
                HighlighterProperty highlighterProp = device == Device.FINGER ? fingerHighlighterProp : stylusHighlighterProp;
                if(highlighterProp != null){
                    highlighterProp.setColor(color);
                    highlighterProp.setSize(size);
                } else {
                    highlighterProp = new HighlighterProperty(color,size);
                }
                updateHighlighterUi(highlighterProp);
                highlighterMenuView.setSize(size);
                highlighterMenuView.setColor(color);
                floatingBarListener.updateCurrentHighlighterPropertyFromFloatingBar(device,color,size);
            }
        });

        penStroke = findViewById(R.id.pen_stroke);

        highlighterStroke = findViewById(R.id.highlighter_stroke);


        inputEraser.setOnClickListener(v -> {

            if(inputEraser.isSelected()){

                hideMenus();
                clearScreen.setVisibility(VISIBLE);
                clearScreenBackground.setVisibility(VISIBLE);
                clearScreenShadow.setVisibility(VISIBLE);
            }else{
                hideMenus();
                toggleInput(v);
                floatingBarListener.updateInputMode(InputMode.ERASER);
            }
        });


        undo.setOnClickListener(v -> {
            floatingBarListener.floatingBarUndo();

        });


        clearScreen.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                floatingBarListener.clearAll();
            }
        });
        clearScreen.setVisibility(INVISIBLE);
        clearScreenBackground.setVisibility(INVISIBLE);
        clearScreenShadow.setVisibility(INVISIBLE);

        takeScreenshot.setOnClickListener(v -> {
            floatingBarListener.takeFloatingBarScreenshot();
        });
        takeScreenshot.setOnLongClickListener(v -> {
            hideMenus();
            setting.setVisibility(VISIBLE);
            settingBackground.setVisibility(VISIBLE);
            settingShadow.setVisibility(VISIBLE);
            share.setVisibility(VISIBLE);
            shareBackground.setVisibility(VISIBLE);
            shareShadow.setVisibility(VISIBLE);
            return true;
        });

        inputExit.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                floatingBarListener.closeFloatingBar();
            }
        });

        setting.setOnClickListener(v -> {
            floatingBarListener.onScreenshotSettingClick();
        });

        share.setOnClickListener(v -> {
            floatingBarListener.onShareScreenshotClick();
        });

        final Resources r = getResources();

        // set exclusive input group
        inputGroup[0] = inputPen;
        inputGroup[1] = inputHighlighter;
        inputGroup[2] = inputEraser;
        inputGroup[3] = undo;
        inputGroup[4] = takeScreenshot;
        inputGroup[5] = inputExit;

        penMenuView.setVisibility(INVISIBLE);
        penMenuShadow.setVisibility(INVISIBLE);
        highlighterMenuView.setVisibility(INVISIBLE);
        highlighterMenuShadow.setVisibility(INVISIBLE);

        updatePenUi(new PenProperty(penDefault,PenProperty.Size.ONE));
        updateHighlighterUi(new HighlighterProperty(highlighterDefault,HighlighterProperty.Size.TWO));
        penMenuView.setColor(penDefault);
        penMenuView.setSize(PenProperty.Size.ONE);
        highlighterMenuView.setColor(highlighterDefault);
        highlighterMenuView.setSize(HighlighterProperty.Size.TWO);



    }

    /**
     * Updates the penProperty button.
     */
    public void updatePenUi(PenProperty penProperty) {
        @ColorInt int white = ContextCompat.getColor(context, R.color.pen_white);
        if (penProperty.getColor() == white) {
            penStroke.setImageResource(penProperty.getFloatingBarOutlinedStrokeRes());
        } else {
            Drawable stroke = ContextCompat.getDrawable(context, penProperty.getFloatingBarStrokeRes());
            if (stroke != null) {
                DrawableCompat.setTint(stroke, penProperty.getColor());
                penStroke.setImageDrawable(stroke);
            }
        }
    }

    /**
     * Updates the highlighterProperty button.
     */
    public void updateHighlighterUi(HighlighterProperty highlighterProperty) {
        @ColorInt int white = ContextCompat.getColor(context, R.color.highlight_white);
        if (highlighterProperty.getColor() == white) {
            highlighterStroke.setImageResource(highlighterProperty.getFloatingBarOutlinedStrokeRes());
        } else {
            Drawable stroke = ContextCompat.getDrawable(context, highlighterProperty.getFloatingBarStrokeRes());
            if (stroke != null) {
                final int color = highlighterProperty.getColor();
                DrawableCompat.setTint(stroke, color | 0xFF000000); // remove transparency
                highlighterStroke.setImageDrawable(stroke);
            }
        }
    }

    public void setPenMenuViewColor(@ColorInt int color){
        penMenuView.setColor(color);
    }

    public void setPenMenuViewSize(PenProperty.Size size){
        penMenuView.setSize(size);
    }

    public void setHighlighterMenuViewColor(@ColorInt int color){
        highlighterMenuView.setColor(color);
    }

    public void setHighlighterMenuViewSize(HighlighterProperty.Size size){
        highlighterMenuView.setSize(size);
    }

    public void setPenMenuProp(PenProperty penProp){
        penMenuView.setColor(penProp.getColor());
        penMenuView.setSize(penProp.getSize());
    }

    public void setHighlighterMenuProp(HighlighterProperty highlighterProp){
        highlighterMenuView.setColor(highlighterProp.getColor());
        highlighterMenuView.setSize(highlighterProp.getSize());
    }

    private void toggleInput(View inputView) {

        inputView.setSelected(true);

        for (View v : inputGroup) {
            if (v != inputView) {
                v.setSelected(false);
            }
        }
    }

    public void syncInputFromMain(int i){
        switch (i){
            case InputMode.PEN:{
                toggleInput(inputPen);
                break;
            }
            case InputMode.HIGHLIGHTER:{
                toggleInput(inputHighlighter);
                break;
            }
            case InputMode.ERASER:{
                toggleInput(inputEraser);
                break;
            }
        }
    }

    public void hideMenus(){
        penMenuView.setVisibility(INVISIBLE);
        penMenuShadow.setVisibility(INVISIBLE);
        highlighterMenuView.setVisibility(INVISIBLE);
        highlighterMenuShadow.setVisibility(INVISIBLE);
        clearScreen.setVisibility(INVISIBLE);
        clearScreenBackground.setVisibility(INVISIBLE);
        setting.setVisibility(INVISIBLE);
        settingBackground.setVisibility(INVISIBLE);
        share.setVisibility(INVISIBLE);
        shareBackground.setVisibility(INVISIBLE);
        settingShadow.setVisibility(INVISIBLE);
        shareShadow.setVisibility(INVISIBLE);
        clearScreenShadow.setVisibility(INVISIBLE);
    }


    public static class InputMode{
        public static final int PEN = 0;
        public static final int HIGHLIGHTER = 1;
        public static final int ERASER = 2;
    }

    public void setFloatingBarListener(FloatingBarListener listener){ floatingBarListener = listener;}

    public interface FloatingBarListener{

        void updateCurrentPenPropertyFromFloatingBar(Device device,int color,PenProperty.Size size);

        void updateCurrentHighlighterPropertyFromFloatingBar(Device device,int color,HighlighterProperty.Size size);

        void updateInputMode(int i);

        void closeFloatingBar();

        void takeFloatingBarScreenshot();

        void floatingBarUndo();

        void clearAll();

        void onScreenshotSettingClick();

        void onShareScreenshotClick();
    }

}
